package dataStruct

import (
	"errors"
	"fmt"
	"reflect"
	"strings"
)

var Dict = map[string]string{
	"}": "{",
	"]": "[",
	")": "(",
}

type stack struct {
	data []interface{}
	kind reflect.Kind
}

func New(kind reflect.Kind) stack {
	return stack{data: []interface{}{}, kind: kind}
}
func (s *stack) Push(v interface{}) {
	if reflect.ValueOf(v).Kind() != s.kind {
		panic("push value is not " + s.kind.String())
	}
	s.data = append(s.data, v)
}
func (s *stack) Pop() (v interface{}) {
	if len(s.data) > 0 {
		v = s.data[len(s.data)-1]
		s.data = s.data[:len(s.data)-1]
		return v
	}
	return nil
}
func (s *stack) Len() int {
	return len(s.data)
}

func (s *stack) GetTop() (v interface{}) {
	if len(s.data) > 0 {
		return s.data[len(s.data)-1]
	}
	return nil
}

func BraceMatch(str string) (err error) {
	stk := New(reflect.String)
	for i := range str {
		a := string(str[i])
		switch {
		case strings.Contains("([{", a):
			stk.Push(a)
		case strings.Contains("]})", a):
			leftVal := stk.Pop()
			needLeftVal := Dict[a]
			if leftVal == nil {
				return errors.New("不匹配,缺少期待的:" + needLeftVal)
			}
			if needLeftVal != leftVal {
				return errors.New(fmt.Sprintf("%s匹配到%s",leftVal,a))
			}
		}
	}
	if stk.Len() > 0 {
		return errors.New(fmt.Sprintf("%s不匹配", stk.Pop()))
	}
	return nil
}
